package com.simple.service;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.simple.entity.cosntant.AdiConstant;
import com.simple.entity.cosntant.ThreadContext;
import com.simple.entity.dto.ConvDto;
import com.simple.entity.dto.ConvEditReq;
import com.simple.entity.dto.ConvSearchReq;
import com.simple.entity.entity.Conversation;
import com.simple.entity.entity.UserMcp;
import com.simple.entity.enums.ErrorEnum;
import com.simple.entity.exception.BaseException;
import com.simple.mapper.ConversationMapper;
import com.simple.util.MPPageUtil;
import com.simple.util.UuidUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @desc
 * @Author Simple
 * @Date 2025/7/8 21:41
 **/
@Slf4j
@Service
public class ConversationService extends ServiceImpl<ConversationMapper, Conversation> {

    @Resource
    private UserMcpService userMcpService;
    @Resource
    private ConversationPresetRelService conversationPresetRelService;

    public int createDefault(Long userId) {
        Conversation conversation = new Conversation();
        conversation.setUuid(UuidUtil.createShort());
        conversation.setUserId(userId);
        conversation.setTitle(AdiConstant.ConversationConstant.DEFAULT_NAME);
        return baseMapper.insert(conversation);
    }

    public Page<ConvDto> search(ConvSearchReq searchReq, Integer currentPage, Integer pageSize) {
        Page<Conversation> page = this.lambdaQuery()
                .eq(Conversation::getIsDeleted, Boolean.FALSE)
                .like(!StringUtils.isBlank(searchReq.getTitle()), Conversation::getTitle, searchReq.getTitle())
                .orderByDesc(Conversation::getId)
                .page(new Page<>(currentPage, pageSize));
        return MPPageUtil.convertToPage(page, ConvDto.class);
    }

    public Boolean edit(String uuid, ConvEditReq convEditReq) {
        Conversation conversation = getOrThrow(uuid);
        Conversation one = new Conversation();
        BeanUtils.copyProperties(convEditReq, one);
        one.setId(conversation.getId());
        if (null != convEditReq.getUnderstandContextEnable()) {
            one.setUnderstandContextEnable(convEditReq.getUnderstandContextEnable());
        }
        if (null != convEditReq.getMcpIds()) {
            List<Long> filteredMcpIds = findEnableMcpIds(convEditReq.getMcpIds());
            one.setMcpIds(StringUtils.join(filteredMcpIds, ","));
        }
        return baseMapper.updateById(one) > 0;
    }

    @Transactional
    public boolean softDel(String uuid) {
        Conversation conversation = getOrThrow(uuid);
        conversationPresetRelService.softDelBy(conversation.getUserId(), conversation.getId());
        return this.lambdaUpdate()
                .eq(Conversation::getId, conversation.getId())
                .set(Conversation::getIsDeleted, Boolean.TRUE)
                .update();
    }

    public Conversation getOrThrow(String uuid) {
        Conversation conversation = this.lambdaQuery()
                .eq(Conversation::getUuid, uuid)
                .eq(Conversation::getIsDeleted, Boolean.FALSE).one();
        if (null == conversation) {
            throw new BaseException(ErrorEnum.A_CONVERSATION_NOT_EXIST);
        }
        if (!conversation.getUserId().equals(ThreadContext.getCurrentUserId())
                && !ThreadContext.getCurrentUser().getIsAdmin()) {
            throw new BaseException(ErrorEnum.A_USER_NOT_AUTH);
        }
        return conversation;
    }

    /**
     * 过滤出有效的MCP服务id列表 | Filter the list of valid MCP service IDs
     *
     * @param mcpIdsInReq 请求中传入的MCP服务id列表 | List of MCP service IDs passed in the request
     * @return 有效的MCP服务id列表 | List of valid MCP service IDs
     */
    private List<Long> findEnableMcpIds(List<Long> mcpIdsInReq) {
        List<Long> result = new ArrayList<>();
        if (CollUtil.isEmpty(mcpIdsInReq)) {
            return result;
        }
        List<UserMcp> userMcpList = userMcpService.searchEnableByUserId(ThreadContext.getCurrentUserId());

        for (Long mcpIdInReq : mcpIdsInReq) {
            if (userMcpList.stream().anyMatch(item -> item.getMcpId().equals(mcpIdInReq))) {
                result.add(mcpIdInReq);
            } else {
                log.warn("User mcp id {} not found or disabled in user mcp list, userId: {}, mcpId:{}", mcpIdInReq, ThreadContext.getCurrentUserId(), mcpIdInReq);
            }
        }
        return result;
    }
}
